package cn.com.connext.scrm.utils;

import cn.com.connext.scrm.exception.ServiceErrorCode;
import cn.com.connext.scrm.service.dto.CouponDTO;
import cn.com.connext.scrm.web.rest.ActivityResource;
import cn.com.connext.scrm.web.rest.OrderResource;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.connext.common.exception.ServiceException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Lamy.Ye
 */
public class ExcelUtil {

    private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);

    private ExcelUtil() {
    }
    public static final String[] ORDER_ITEM_KEYS =  {"orderName","count","state","orderTime","name","mobile","address","activityType","activityName"};

    public static final String[] ORDER_ITEM_COLUMNNAMES={"产品名称","数量","状态","订单时间","姓名","手机号","地址","活动类型","活动名称"};

    public static final String ORDER_ITEM_SHEET_NAME = "订单明细";

    private final static String xls = "xls";
    private final static String xlsx = "xlsx";

    private static Set<String> decimalFiledSet = new HashSet<>();

    public static Workbook getWorkBook(MultipartFile file) {
        //获得文件名
        String fileName = file.getOriginalFilename();
        //创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        try {
            //获取excel文件的io流
            InputStream is = file.getInputStream();
            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if (fileName.endsWith(xls)) {
                //2003
                workbook = new HSSFWorkbook(is);
            } else if (fileName.endsWith(xlsx)) {
                //2007
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return workbook;
    }

    public static List<Map<String, Object>> setFirstItems(String sheetName){
        List<Map<String, Object>> exlItemList = new ArrayList<>();
        Map<String, Object> map_0 = new HashMap<>(1 );
        map_0.put("sheetName",sheetName);
        exlItemList.add(map_0);
        return exlItemList;
    }

    /**
     * 获取属性值
     * @param thisClass
     * @param fieldName
     * @return
     */
    public static String getFieldValue(Object thisClass, String fieldName) {
        String fieldValue = "";
        String[] fieldNames = fieldName.split("_");
        for (int i = 0; i < fieldNames.length; i++) {
            Object value = new Object();
            if (fieldNames[i].contains("-")) {
                fieldNames[i] = fieldNames[i].split("-")[0];
            }
            try {
                String methodName = fieldNames[i].substring(0, 1).toUpperCase() + fieldNames[i].substring(1);
                try {
                    value = getMethodByFields(thisClass, methodName);
                } catch (NoSuchMethodException noME) {
                    try {
                        value = getMethodByFieldsToP(thisClass, methodName);
                    } catch (NoSuchMethodException noMEP) {
                        return "";
                    }
                }
            } catch (Exception e) {
                log.error("# 反射获取属性值异常异常，msg={}",e.getMessage(),e);
            }
            fieldValue += value == null ? "" : value.toString();
        }
        if (fieldName.equals("reportDate") || fieldName.equals("orderDate") || fieldName.equals("date")) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date parse = format.parse(fieldValue);
                return format.format(parse);
            } catch (ParseException e) {
                e.printStackTrace();
                return fieldValue;
            }
        } else if (decimalFiledSet.contains(fieldName)) {
            DecimalFormat df = new DecimalFormat("0.00");
            df.setMaximumFractionDigits(2);
            df.setGroupingSize(0);
            df.setRoundingMode(RoundingMode.FLOOR);
            return df.format(new BigDecimal(fieldValue));
        }
        return fieldValue;
    }

    /**
     * 根据属性获当前类中get方法
     * @param thisClass
     * @param methodName
     */
    private static Object getMethodByFields(Object thisClass,  String methodName)
        throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
        InvocationTargetException {
        Method method = thisClass.getClass().getDeclaredMethod("get" + methodName);
        return method.invoke(thisClass);
    }

    /**
     * 根据属性获当前类父类中get方法
     * @param thisClass
     * @param methodName
     * @return
     */
    private static Object getMethodByFieldsToP(Object thisClass,String methodName)
        throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
        InvocationTargetException {
        Method method = thisClass.getClass().getSuperclass().getDeclaredMethod("get" + methodName);
        return method.invoke(thisClass);
    }

    /**
     * 创建excel文档，
     *
     * @param list
     *            数据
     * @param keys
     *            list中map的key数组集合
     * @param columnNames
     *            excel的列名
     */
    public static Workbook createWorkBook(List<Map<String, Object>> list, String[] keys, String columnNames[]) {
        Workbook wb = new HSSFWorkbook();
        Sheet sheet = wb.createSheet(list.get(0).get("sheetName").toString());
        for (int i = 0; i < keys.length; i++) {
            sheet.setColumnWidth((short) i, (short) (35.7 * 150));
        }
        Row row = sheet.createRow((short) 0);
        CellStyle cs = wb.createCellStyle();
        CellStyle cs2 = wb.createCellStyle();
        Font f = wb.createFont();
        Font f2 = wb.createFont();
        f.setFontHeightInPoints((short) 10);
        f.setColor(IndexedColors.BLACK.getIndex());
        f2.setFontHeightInPoints((short) 10);
        f2.setColor(IndexedColors.BLACK.getIndex());
        cs.setFont(f);
        cs2.setFont(f2);
        for (int i = 0; i < columnNames.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(columnNames[i]);
            cell.setCellStyle(cs);
        }
        // 设置每行每列的值
        for (int i = 1; i < list.size(); i++) {
            Row row1 = sheet.createRow(i);
            for (short j = 0; j < keys.length; j++) {
                Cell cell = row1.createCell(j);
                cell.setCellValue(list.get(i).get(keys[j]) == null ? " " : list.get(i).get(keys[j]).toString());
                cell.setCellStyle(cs2);
            }
        }
        return wb;
    }
    public static void exportExcel(HttpServletResponse response, Workbook wb,
                                   String fileName) throws IOException {
        // 如果文件名有中文，必须URL编码
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.reset();

        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
        // ContentType 可以不设置
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        wb.write(response.getOutputStream());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }

    /**
     * 导出
     * @param response
     * @param data
     * @param fileName
     * @param sheetName
     * @param clazz
     * @throws Exception
     */
    public static void writeExcel(HttpServletResponse response, List<? extends Object> data, String fileName, String sheetName, Class clazz) throws Exception {
        //表头样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置表头居中对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //内容样式
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠左对齐
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        EasyExcel.write(getOutputStream(fileName, response), clazz).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).registerWriteHandler(horizontalCellStyleStrategy).doWrite(data);
    }
    private static OutputStream getOutputStream(String fileName, HttpServletResponse response) throws Exception {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        return response.getOutputStream();
    }

}
